
`include "mux1x4v2_defs.v"
`include "mux1x2_defs.v"
`include "shifter_defs.v"
`include "alu_defs.v"

`timescale 1ns / 1ps

module alu_instr_dec(
	i_instr,
	
	o_sel_alu_op_a,
	o_sel_alu_op_b,
	o_cmd_shifter_reg_file,
	o_cmd_reg_file_wr_en,
	o_cmd_shifter_q_reg,
	o_cmd_q_reg_ld_en,
	o_sel_alu_out
);

input [8:0] i_instr;

output [1:0] 	o_sel_alu_op_a;
output [1:0] 	o_sel_alu_op_b;
output [1:0] 	o_cmd_shifter_reg_file;
output 				o_cmd_reg_file_wr_en;
output [1:0]	o_cmd_shifter_q_reg;
output 				o_cmd_q_reg_ld_en;
output 				o_sel_alu_out;


reg [4:0] w_alu_op_sel;
reg [6:0] w_alu_dest_ctrl;

assign { 	o_sel_alu_op_a, 
					o_sel_alu_op_b } 			= w_alu_op_sel;

assign { 	o_cmd_shifter_reg_file, 
					o_cmd_reg_file_wr_en, 
					o_cmd_shifter_q_reg, 
					o_cmd_q_reg_ld_en, 
					o_sel_alu_out } 			= w_alu_dest_ctrl;

always@( i_instr[2:0] )
begin
	case( i_instr[2:0] )		
		// ops												// op A sel				// op B sel		
		`ALU_OP_AQ : w_alu_op_sel = { `MUX1X4v2_SEL_1, `MUX1X4v2_SEL_2 }; 
		`ALU_OP_AB : w_alu_op_sel = { `MUX1X4v2_SEL_1, `MUX1X4v2_SEL_1 }; 
		`ALU_OP_ZQ : w_alu_op_sel = { `MUX1X4v2_SEL_2, `MUX1X4v2_SEL_2 }; 
		`ALU_OP_ZB : w_alu_op_sel = { `MUX1X4v2_SEL_2, `MUX1X4v2_SEL_1 }; 
		`ALU_OP_ZA : w_alu_op_sel = { `MUX1X4v2_SEL_2, `MUX1X4v2_SEL_0 }; 
		`ALU_OP_DA : w_alu_op_sel = { `MUX1X4v2_SEL_0, `MUX1X4v2_SEL_0 }; 
		`ALU_OP_DQ : w_alu_op_sel = { `MUX1X4v2_SEL_0, `MUX1X4v2_SEL_2 }; 
		`ALU_OP_DZ : w_alu_op_sel = { `MUX1X4v2_SEL_0, `MUX1X4v2_SEL_3 }; 
	endcase
end

`define ALU_MNEM_QREG		3'b000	
`define ALU_MNEM_NOP		3'b001
`define ALU_MNEM_RAMA		3'b010
`define ALU_MNEM_RAMF		3'b011
`define ALU_MNEM_RAMQD	3'b100
`define ALU_MNEM_RAMD		3'b101
`define ALU_MNEM_RAMQU	3'b110
`define ALU_MNEM_RAMU		3'b111

always@( i_instr[8:6] )
begin
	case( i_instr[8:6] )
		// mnemonic														reg file shifter			reg we	q reg shifter				q reg ld	out sel	
		`ALU_MNEM_QREG 	: w_alu_dest_ctrl = { `SHIFTER_SEL_NOP, 			1'b0, `SHIFTER_SEL_NOP, 			1'b1, `MUX1X2_SEL_1 };
		`ALU_MNEM_NOP 	: w_alu_dest_ctrl = { `SHIFTER_SEL_NOP, 			1'b0, `SHIFTER_SEL_NOP, 			1'b0, `MUX1X2_SEL_1 };
		`ALU_MNEM_RAMA 	: w_alu_dest_ctrl = { `SHIFTER_SEL_NOP, 			1'b1, `SHIFTER_SEL_NOP, 			1'b0, `MUX1X2_SEL_0 };
		`ALU_MNEM_RAMF 	: w_alu_dest_ctrl = { `SHIFTER_SEL_NOP, 			1'b1, `SHIFTER_SEL_NOP, 			1'b0, `MUX1X2_SEL_1 };
		`ALU_MNEM_RAMQD : w_alu_dest_ctrl = { `SHIFTER_SEL_ONE_RIGHT,	1'b1, `SHIFTER_SEL_ONE_RIGHT, 1'b1, `MUX1X2_SEL_1 };
		`ALU_MNEM_RAMD 	: w_alu_dest_ctrl = { `SHIFTER_SEL_ONE_RIGHT,	1'b1, `SHIFTER_SEL_NOP, 			1'b0, `MUX1X2_SEL_1 };
		`ALU_MNEM_RAMQU : w_alu_dest_ctrl = { `SHIFTER_SEL_ONE_LEFT, 	1'b1, `SHIFTER_SEL_ONE_LEFT, 	1'b1, `MUX1X2_SEL_1 };
		`ALU_MNEM_RAMU 	: w_alu_dest_ctrl = { `SHIFTER_SEL_ONE_LEFT, 	1'b1, `SHIFTER_SEL_NOP, 			1'b0, `MUX1X2_SEL_1 };
	endcase
end

endmodule
